package com.builder.inputeditor;

import com.gooddies.events.BooleanEvent;
import com.gooddies.graphics.InteractiveIcon;
import com.gooddies.graphics.LinkIconLabel;
import com.swingson.SwingsonGui;
import com.swingson.SwingsonGuiBuilder;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Window;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;

/**
 * @author Dmitry
 */
public class ReorderFieldsDialog<T> extends JDialog {
    private final List<T> objects;
    private static final InteractiveIcon upIcon = new InteractiveIcon("/com/builder/icons/up.png");
    private static final InteractiveIcon downIcon = new InteractiveIcon("/com/builder/icons/down.png");
    private boolean modalResult = false;
    private final JPanel componentsHolder = new JPanel();

    public ReorderFieldsDialog(Window owner, List<T> objectsToReorder) {
        super(owner, ModalityType.DOCUMENT_MODAL);
        this.objects = objectsToReorder;
        init();
    }

    private void init() {
        setTitle("Reorder elements");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        componentsHolder.setLayout(new MigLayout());
        for (Object obj : objects) {
            JPanel panel = createPanel(obj);
            componentsHolder.add(panel, "wrap,width 99%");
        }

        SwingsonGui gui = SwingsonGuiBuilder.createGuiFromJsonInPackage(this);
    }

    private JPanel createPanel(Object obj) {
        final JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(100, 25));
        panel.setMinimumSize(new Dimension(100, 25));
        panel.putClientProperty("object", obj);
        JLabel label = new JLabel(obj.toString());
        label.setMaximumSize(new Dimension(180, 20));
        label.setPreferredSize(new Dimension(180, 20));
        panel.add(label);
        LinkIconLabel upButton = new LinkIconLabel(null, upIcon);
        LinkIconLabel downButton = new LinkIconLabel(null, downIcon);
        panel.add(upButton);
        panel.add(downButton);
        upButton.addClickEvent(new BooleanEvent() {
            @Override
            public boolean fireEvent(Object aThis) {
                up(panel);
                return false;
            }
        });
        downButton.addClickEvent(new BooleanEvent() {
            @Override
            public boolean fireEvent(Object aThis) {
                down(panel);
                return false;
            }
        });

        return panel;
    }

    private int getComponentIndex(JPanel p) {
        int index = -1;
        for (Component c : componentsHolder.getComponents()) {
            index++;
            if (c == p) {
                return index;
            }
        }

        return -1;
    }

    private void up(JPanel p) {
        int index = getComponentIndex(p);
        if (index != 0) {
            componentsHolder.remove(p);
            componentsHolder.add(p, "wrap,width 99%", index - 1);
        }

        revalidate();
        validate();
        repaint();
    }

    private void down(JPanel p) {
        int index = getComponentIndex(p);
        if (index != (componentsHolder.getComponentCount() - 1)) {
            componentsHolder.remove(p);
            componentsHolder.add(p, "wrap,width 99%", index + 1);
        }

        revalidate();
        validate();
        repaint();
    }

    private void onOk() {
        modalResult = true;
        setVisible(false);
        dispose();
    }

    private void onCancel() {
        modalResult = false;
        setVisible(false);
        dispose();
    }

    public List<T> getOrder() {
        List resultList = new ArrayList();
        for (Component component : componentsHolder.getComponents()) {
            Object obj = ((JComponent) component).getClientProperty("object");
            resultList.add(obj);
        }

        return resultList;
    }

    public boolean showDialog() {
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        return modalResult;
    }
}
